package com.example.onlinemonitoring.comCenter;

import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.Gbzdhistory;
import com.example.onlinemonitoring.model.Gbzdsensor;
import com.example.onlinemonitoring.serviceImpl.GbzdsensorServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.context.annotation.Scope;
import java.text.ParseException;
import java.util.Date;

/**
 * 干变振动
 */
@Service("gbzdCom")
@Scope("prototype")
public class DbzdCom extends CommPortManager {
    @Autowired
    private GbzdsensorServiceImpl gbzdserviceimpl;

    @Override
    public void receiveData(String str) {
        str = str.toUpperCase();
        setText(str);
        if (!str.substring(2, 4).equals("03"))
            return;
        int addr = parseHex4(str.substring(0, 2));
        String content = str.substring(6, 14);
        reSend[addr] = 0;
        addrindex++;
        setText("设备返回数据： 站点号：" + ad.getStationid() + " 设备组：" + ad.getDevicegroup() + " 设备地址：" + addr);
        for (int i = 1; i <= ad.getPointcount(); i++) {
            Gbzdsensor gbzd = new Gbzdsensor();
            gbzd.setStationid(ad.getStationid());
            gbzd.setDevicegroup(ad.getDevicegroup());
            gbzd.setDeviceaddr(addr);
            gbzd.setPointaddr(i);
            Gbzdsensor record = gbzdserviceimpl.getModel(gbzd);
            if (record == null) {
                setText("当前数据库无监测点：设备地址" + addr + "的监测点" + i + " ！ 请先添加该监测点！");
                continue;
            }
            if (record.getInuse() == 1) {
                SensorData(record, gbzd, parseHex4(content.substring((i - 1) * 4, 4 + (i - 1) * 4)));
            }
        }
    }

    void SensorData(Gbzdsensor record, Gbzdsensor gb, int value) {
        if (record.getLastdenominator() == null) {
            setText("设备地址" + record.getDeviceaddr() + "的监测点" + record.getPointaddr() + " 未设置系数！");
            return;
        }
        float val = value * 1f * record.getLastdenominator();
        setText(record.getPointname() + "：" + val + " " + record.getLastunit());
        if (record.getAlarmvalue() == null || record.getAlarmrelievevalue() == null || record.getWarnvalue() == null
                || record.getWarnrelievevalue() == null) {
            setText("设备地址" + record.getDeviceaddr() + "的监测点" + record.getPointaddr() + " 未设置报警值！");
            return;
        }
        gb.setLastdata(val);
        gb.setLastdatatime(new Date());
        gb.setLastalarmlevel(GetAlarmStatus(HexUtil.isnull(gb.getLastdata()), HexUtil.isnull(record.getAlarmvalue()),
                HexUtil.isnull(record.getAlarmrelievevalue()), HexUtil.isnull(record.getWarnvalue()),
                HexUtil.isnull(record.getWarnrelievevalue()),
                HexUtil.isnull(record.getLastalarmlevel()), true, "摆动幅度", record.getDevicegroup(),
                record.getDeviceaddr(), record.getPointname(), record.getPointaddr()));
        // 报警消息
        gb.setLastalarmmessage(GetAlarmMessage(gb.getLastalarmlevel(), "摆动幅度"));
        gb.setLastcommunicationstatus(0);
        gb.setLasthisdatatime(addHistory(record));
        if (gbzdserviceimpl.Update(gb, false) == 0) {
            setText("更新实时数据失败，请检查数据库连接");
        }
    }

    private Date addHistory(Gbzdsensor sensor) {
        if (sensor != null) {
            if (sensor.getLasthisdatatime() == null) {
                add(sensor);
                return new Date();
            } else {
                long lasttime = 0;
                long nowtime = 0;
                try {
                    lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                    nowtime = HexUtil.todate(new Date()).getTime();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                int timersp = 60000;
                if (sensor.getLastalarmlevel() != 0) {
                    timersp = ad.getHisalarmtimersp() * 1000;
                } else {
                    timersp = ad.getHistimersp() * 1000;
                }
                if (lasttime + timersp < nowtime) {
                    add(sensor);
                    return new Date();
                }
            }
        }
        return null;
    }

    private void add(Gbzdsensor sensor) {
        Gbzdhistory his = new Gbzdhistory();
        his.setStationid(sensor.getStationid());
        his.setDevicegroup(sensor.getDevicegroup());
        his.setDeviceaddr(sensor.getDeviceaddr());
        his.setAddrname(sensor.getAddrname());
        his.setPointaddr(sensor.getPointaddr());
        his.setPointname(sensor.getPointname());
        his.setData(sensor.getLastdata());
        his.setDatatime(sensor.getLastdatatime());
        his.setAlarmlevel(sensor.getLastalarmlevel());
        his.setAlarmmessage(sensor.getLastalarmmessage());
        his.setDenominator(sensor.getLastdenominator());
        his.setUnit(sensor.getLastunit());
        his.setName(sensor.getLastname());
        gbzdserviceimpl.Add(his);
    }

    // 指定使用beanname为threadPool的线程池
    @Async("threadPool")
    public void startSendThread(Appdevice Appdevice) throws Exception {
        checkType = "crc16";
        issend.put(Thread.currentThread().getId(), true);
        String cstr = "";
        String cmdtype = "";
        String nametype = "";
        int timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
        while (issend.get(Thread.currentThread().getId()) != null) {
            if (isrun) {
                if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                    addrindex = Appdevice.getAddrmin();
                cstr = String.format(Appdevice.getCmd(), String.format("%02X", addrindex));
                cstr = cstr + CRC16.calcCrc16(cstr);
                Send(cstr);
                reSend[addrindex]++;
                if (reSend[addrindex] > 3) {
                    gbzdserviceimpl.UpdateStatus(ad, addrindex, 1);
                    reSend[addrindex] = 0;
                    addrindex++;
                }
            } else if (rescode != 0) {
                setText(resmsg[rescode]);
            }
            Thread.sleep(timersp);
        }
    }
}
